﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Windows.Forms;
using DataBaseLayer.Abstractions;
using DataBaseLayer.Dto;
using DocumentManager.Abstractions.Factories;
using DocumentManager.Abstractions.Interfaces;
using DocumentManager.Abstractions.Interfaces.Helpers;
using DocumentManager.Common;
using DocumentManager.Enums;

namespace DocumentManager.Forms
{
	public partial class frmDismissalOrder : Form, IOrderForm, IForm
	{
		#region Variables

		private int? _orderId;

		private readonly IWordDocumentAdapter _wordDocumentAdapter;
		private readonly ServiceBaseFactory _serviceFactory;
		private readonly IApplicationConfiguration _applicationConfiguration;
		private readonly FormBaseFactory _formFactory;

		#endregion

		#region Private Properties

		private bool IsValidFormData
		{
			get
			{
				int paidDays;
				return !string.IsNullOrWhiteSpace(txtAuthorSignature.Text)
					   && !string.IsNullOrWhiteSpace(txtNumber.Text)
					   && !string.IsNullOrWhiteSpace(txtPerson.Text)
					   && !string.IsNullOrWhiteSpace(txtPlace.Text)
					   && !string.IsNullOrWhiteSpace(txtProfession.Text)
					   && !string.IsNullOrWhiteSpace(txtStatementAuthor.Text)
					   && !string.IsNullOrWhiteSpace(txtPaidDays.Text)
					   && int.TryParse(txtPaidDays.Text, out paidDays);
			}
		}

		#endregion

		#region Constructors

		public frmDismissalOrder(
			ServiceBaseFactory serviceFactory,
			IApplicationConfiguration applicationConfiguration,
			IWordDocumentAdapter wordDocumentAdapter,
			FormBaseFactory formFactory)
		{
			if (serviceFactory == null)
				throw new ArgumentNullException(string.Format("service Factory"));
			_serviceFactory = serviceFactory;

			if (applicationConfiguration == null)
				throw new ArgumentNullException(string.Format("application Configuration"));
			_applicationConfiguration = applicationConfiguration;

			if (wordDocumentAdapter == null)
				throw new ArgumentNullException(string.Format("word Document Adapter"));
			_wordDocumentAdapter = wordDocumentAdapter;

			if (formFactory == null)
				throw new ArgumentNullException(string.Format("form Factory"));
			_formFactory = formFactory;

			InitializeComponent();
		}

		#endregion

		#region Form Actions

		private void btnSave_Click(object sender, EventArgs e)
		{
			this.Enabled = false;

			if (IsValidFormData)
			{
				var newLogOrder = new LogOrderData
				{
					Date = dtpDate.Value,
					Description = string.Format("Приказ об увольнении сотрудника"),
					Number = txtNumber.Text,
					Performer = _applicationConfiguration.Performer
				};
				var newOrder = new DismissalOrderData
				{
					Id = _orderId.GetValueOrDefault(),
					Number = txtNumber.Text,
					Date = dtpDate.Value,
					Person = txtPerson.Text,
					Profession = txtProfession.Text,
					Place = txtPlace.Text,
					StartDate = dtpStartDate.Value,
					PaidDays = int.Parse(txtPaidDays.Text),
					AuthorSignature = txtAuthorSignature.Text,
					StatementAuthor = txtStatementAuthor.Text
				};

				var service = _serviceFactory.CreateDismissalOrdersService();
				if (service == null)
					throw new ArgumentNullException(string.Format("Dismissal Orders Service"));

				if (_orderId.HasValue)
					service.UpdateOrder(newOrder, newLogOrder);
				else
					service.CreateOrder(newOrder, newLogOrder);

				MessageBox.Show(Constants.SAVE_OPERATION_SUCCESFULL_COMPLETE);
			}
			else
				MessageBox.Show(Constants.EMPTY_FIELDS_ON_FORM_EXCEPTION_MESSAGE);

			this.Enabled = true;
		}

		private void btnGenerateDocument_Click(object sender, EventArgs e)
		{
			this.Enabled = false;

			try
			{
				var templateFile = _applicationConfiguration.GetOrderTemplateFilePathByOrderType(OrderType.Dismissal);

				var newTempFilePath = _wordDocumentAdapter
					.CreateTempDocumentByTemplate(
						templateFile,
						_applicationConfiguration.TempOrderDocumentName);
				if (string.IsNullOrWhiteSpace(newTempFilePath))
					return;

				var data = CreateOrderMergedData();
				_wordDocumentAdapter.MergeDocumentData(newTempFilePath, data);

				var documentViewerForm = _formFactory.CreateDocumentViewerForm(newTempFilePath);
				if (documentViewerForm != null)
					documentViewerForm.ShowDialog();
			}
			catch (Exception ex)
			{
				MessageBox.Show(string.Format("При попытки печати документа возникла ошибка!{0}{1}", Environment.NewLine, ex.Message));
			}

			this.Enabled = true;
		}

		#endregion

		#region IOrderForm Members

		public int? OrderId
		{
			get { return _orderId; }
			set
			{
				_orderId = value;
				FillFormElements();
			}
		}

		public IDictionary<string, string> CreateOrderMergedData()
		{
			var result = new Dictionary<string, string>
			{
				{ Constants.NUMBER_FIELD_NAME, txtNumber.Text },
				{ Constants.DATE_FIELD_NAME, dtpDate.Value.ToShortDateString() },
				{ Constants.PERSON_FIELD_NAME, txtPerson.Text },
				{ Constants.PROFESSION_FIELD_NAME, txtProfession.Text },
				{ Constants.PLACE_FIELD_NAME, txtPlace.Text },
				{ Constants.START_DATE_FIELD_NAME, dtpStartDate.Value.ToShortDateString() },
				{ Constants.PAID_DAYS_FIELD_NAME, txtPaidDays.Text },
				{ Constants.STATEMENT_AUTHOR_FIELD_NAME, txtStatementAuthor.Text },
				{ Constants.DIRECTOR_FIELD_NAME, _applicationConfiguration.Director ?? string.Empty },
				{ Constants.AUTHOR_SIGNATURE_FIELD_NAME, txtAuthorSignature.Text }
			};

			return result;
		}

		#endregion

		#region IForm Members

		public void FillFormElements()
		{
			var service = _serviceFactory.CreateDismissalOrdersService();
			var order = service != null ? service.GetOrderById(_orderId.GetValueOrDefault()) : null;
			if (order == null)
			{
				ClearFormElements();
				return;
			}

			txtNumber.Text = order.Number;
			dtpDate.Value = order.Date;
			txtPerson.Text = order.Person;
			txtProfession.Text = order.Profession;
			txtPlace.Text = order.Place;
			dtpStartDate.Value = order.StartDate;
			txtPaidDays.Text = order.PaidDays.ToString(CultureInfo.InvariantCulture);
			txtAuthorSignature.Text = order.AuthorSignature;
			txtStatementAuthor.Text = order.StatementAuthor;
		}

		public void ClearFormElements()
		{
			txtNumber.Text = txtPerson.Text = txtProfession.Text = txtPlace.Text
				= txtAuthorSignature.Text = txtStatementAuthor.Text = txtPaidDays.Text = string.Empty;
			dtpDate.Value = dtpStartDate.Value = DateTime.Now;
		}

		#endregion
	}
}
